package route

import (
	"fmt"
	"github.com/gin-gonic/gin"
	"k9-panel/admin/dashboard"
	controller2 "k9-panel/app/adapter/http/controller"
	"k9-panel/app/adapter/http/middleware"
	"k9-panel/app/model"
	"k9-panel/app/response"
	"k9-panel/app/service"
	"k9-panel/config"
	"net/http"
)

func CORSMiddleware() gin.HandlerFunc {
	return func(c *gin.Context) {
		// 设置允许跨域的来源
		c.Writer.Header().Set("Access-Control-Allow-Origin", "*")
		// 设置允许的请求方法
		c.Writer.Header().Set("Access-Control-Allow-Methods", "POST, GET, OPTIONS, PUT, DELETE")
		// 设置允许的请求头
		c.Writer.Header().Set("Access-Control-Allow-Headers", "Content-Type, Content-Length, Accept-Encoding, X-CSRF-Token, Authorization, accept, origin, Cache-Control, X-Requested-With, token")
		// 设置是否允许携带凭证
		c.Writer.Header().Set("Access-Control-Allow-Credentials", "true")

		// 如果是 OPTIONS 请求，直接返回状态码 204
		if c.Request.Method == "OPTIONS" {
			c.AbortWithStatus(http.StatusNoContent)
			return
		}

		// 继续处理请求
		c.Next()
	}
}
func TokenPullMiddleware() gin.HandlerFunc {

	return func(c *gin.Context) {
		fmt.Println("req path", c.Request.URL.Path)

		// 设置允许跨域的来源
		token := c.GetHeader("token")
		envName := c.Query("envName")
		if envName == "" {
			c.JSON(200, response.Fail[string]("envName 参数丢失！"))
			return
		}
		projectName := c.Query("projectName")
		if projectName == "" {
			c.AbortWithStatus(http.StatusBadRequest)

			//c.JSON(200, response.Fail[string]("projectName 参数丢失！"))
			return
		}
		userToken, _ := service.UserToken.Query(c, token)
		if userToken == nil {
			c.AbortWithStatus(http.StatusBadRequest)

			//c.JSON(200, response.Fail[string]("userToken 不存在！"))
			return
		}
		project, err2 := service.Project.Get(&model.Project{Name: projectName})
		if err2 != nil || project.Name == "" {
			c.AbortWithStatus(http.StatusBadRequest)

			//c.JSON(200, response.Fail[string]("project 不存在！"))
			return
		}

		env, err2 := service.Environment.GetByModel(&model.Environment{Name: envName})
		if err2 != nil || project.Name == "" {
			c.AbortWithStatus(http.StatusBadRequest)
			return
		}
		accessEnv, _ := userToken.CanAccessEnv(env.ID, nil)
		accessProject, _ := userToken.CanAccessProject(project.ID, nil)
		if !accessEnv || !accessProject {
			c.AbortWithStatus(http.StatusUnauthorized)
			return
		} else {
			// 继续处理请求
			c.Next()
		}

	}
}
func Init(router *gin.Engine) {
	// Recovery middleware recovers from any panics and writes a 500 if there was one.
	router.Use(gin.CustomRecoveryWithWriter(gin.DefaultWriter, func(c *gin.Context, err any) {
		errMsg := err.(error).Error()
		c.JSON(http.StatusOK, response.Fail[string](errMsg))

	}))
	router.GET("/", func(c *gin.Context) {
		file, err := dashboard.StaticFiles.ReadFile("dist/index.html")
		if err != nil {
			return
		}
		c.Data(http.StatusOK, "text/html; charset=utf-8", file)
	})
	router.GET("/public/*filepath", func(c *gin.Context) {
		// 获取动态路径参数
		filepath := c.Param("filepath")
		// 创建一个 HTTP 文件服务器
		httpFileServer := http.FileServer(http.FS(dashboard.StaticFiles))
		// 构造完整的文件路径
		// 然后将请求转发给 http.FileServer
		c.Request.URL.Path = "dist/public/" + filepath
		// 调用 http.FileServer 处理请求
		httpFileServer.ServeHTTP(c.Writer, c.Request)
	})

	//internal/v1/config/publish
	internalV1 := router.Group("internal/v1")
	internalV1.Use(TokenPullMiddleware())
	internalV1.GET("config/publish", controller2.HistoryConfig.QueryPublish)

	router.Use(CORSMiddleware())
	handle, _ := middleware.NewJwtMiddleware()

	middleware.RegisterRoute(router, handle)
	//router.POST("/auth", controller2.Auth.Login)

	group := router.Group("v1", handle.MiddlewareFunc())

	group.GET("vvv", func(c *gin.Context) {
		c.JSON(200, gin.H{"vvv": "vvv"})
	})
	fmt.Println("route config file:", config.Cfg)

	group.POST("project/add", controller2.Project.Add)
	group.POST("project/delete", controller2.Project.Delete)
	group.POST("project/update", controller2.Project.Update)
	group.GET("project/list", controller2.Project.List)

	group.GET("env/list", controller2.Environment.List)
	group.POST("env/add", controller2.Environment.Add)
	group.POST("env/batch", controller2.Environment.Batch)
	group.POST("env/delete", controller2.Environment.Delete)
	group.POST("env/update", controller2.Environment.Update)
	group.GET("env/projects", controller2.Environment.Projects)

	group.POST("config/base/delete", controller2.BaseConfig.Delete)
	group.POST("config/base/update", controller2.BaseConfig.Update)
	group.GET("config/base/get", controller2.BaseConfig.Get)

	group.POST("config/derived/update", controller2.DerivedConfig.Update)
	group.GET("config/derived/get", controller2.DerivedConfig.Get)
	group.POST("config/derived/preview", controller2.DerivedConfig.Preview)

	group.POST("config/history/delete", controller2.HistoryConfig.Delete)
	group.POST("config/history/publish", controller2.HistoryConfig.Publish)
	group.POST("config/history/unpublish", controller2.HistoryConfig.UnPublish)
	group.GET("config/history/get", controller2.HistoryConfig.Get)
	group.POST("config/history/list", controller2.HistoryConfig.List)

	group.GET("user_token/list", controller2.UserToken.List)
	group.POST("user_token/delete", controller2.UserToken.Delete)
	group.POST("user_token/update", controller2.UserToken.Update)

	group.GET("account/list", controller2.Account.List)
	group.POST("account/delete", controller2.Account.Delete)
	group.POST("account/add", controller2.Account.Add)
	group.POST("account/updatePassword", controller2.Account.UpdatePassword)
	group.POST("account/updateAccountPassword", controller2.Account.UpdatePassword)
	group.POST("account/UpdateOtherPassword", controller2.Account.UpdateOtherPassword)

	group.POST("perm/set", controller2.Account.PermSet)

}
